/*  This file is part of o.O.

    o.O is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    o.O is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with o.O.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2013 Oliver Katz */

/* HOW'S IT GOING?

If you are trying to use o.O, this is not the place to look. Try builder.h. */

#ifndef __OO_PARSING_RECURSIVE_DESCENT_H
#define __OO_PARSING_RECURSIVE_DESCENT_H

#include "types.h"
#include <typeinfo>

namespace oO
{
	class Parser
	{
	protected:
		std::string name;
		bool strict;
		bool debug;

	public:
		Parser();
		Parser(std::string n);
		void enableDebugging();
		void disableStrict();
		void debugInput(std::vector<Token> t);
		void debugOutput(std::pair<unsigned int, AST> rtn);
		void error(Error e);
		std::string getName();
		virtual std::pair<unsigned int, AST> check(std::vector<Token> t, Page p);
	};

	class Leaf : public Parser
	{
	protected:
		std::string match;

	public:
		Leaf();
		Leaf(std::string n);
		Leaf(std::string n, std::string m);
		std::pair<unsigned int, AST> check(std::vector<Token> t, Page p);
	};

	class Sequence : public Parser
	{
	private:
		std::vector<std::pair<std::string, Parser*> > content;

	public:
		Sequence();
		Sequence(std::string n);
		void appendLabeled(std::string l, Parser *p);
		void appendChild(Parser *p);
		std::pair<unsigned int, AST> check(std::vector<Token> t, Page p);
	};

	class Many : public Parser
	{
	private:
		Parser *content;

	public:
		Many();
		Many(std::string n, Parser *p);
		std::pair<unsigned int, AST> check(std::vector<Token> t, Page p);
	};

	class Branch : public Parser
	{
	private:
		std::vector<Parser*> content;

	public:
		Branch();
		Branch(std::string n);
		Branch(std::string n, std::vector<Parser*> c);
		Branch &operator << (Parser *p);
		std::pair<unsigned int, AST> check(std::vector<Token> t, Page p);
	};
}

#endif
